<template>
	<div class="v-popup">
		<c-overlay v-model="overlayVisiible" @click="closeOnClickOverlay && hide()"></c-overlay>
		<transition :name="'slide-' + position">
			<div
				class="popup-content"
				:class="[
					{
						'round': round,
						'position-bottom': position === 'bottom',
						'position-top': position === 'top',
						'position-left': position === 'left',
						'position-right': position === 'right',
						'safe-area-inset-top': safeAreaInsetTop,
						'safe-area-inset-bottom': safeAreaInsetBottom,
					},
				]"
				:style="[
					{
						'z-index': zIndex,
						'--round-size': roundSizeRpx + 'px',
						'--duration': duration + 'ms',
					},
				]"
				v-if="visible"
				v-show="showContent"
			>
				<div v-if="closeable" class="close-icon" @click="hide"></div>
				<slot></slot>
			</div>
		</transition>
	</div>
</template>

<script>
let callback = () => {}

export default {
	name: "v-popup",
	props: {
		zIndex: {
			type: [Number, String],
			default: 1001,
		},
		position: {
			type: String,
			default: "bottom", // bottom, top, left, right
		},
		duration: {
			type: [Number, String],
			default: 300,
		},
		round: {
			type: Boolean,
			default: false,
		},
		roundSize: {
			type: [Number, String],
			default: 30,
		},
		closeOnClickOverlay: {
			type: Boolean,
			default: true,
		},
		closeable: {
			type: Boolean,
			default: true,
		},
		safeAreaInsetTop: {
			type: Boolean,
			default: true,
		},
		safeAreaInsetBottom: {
			type: Boolean,
			default: true,
		},
	},
	data() {
		return {
			overlayVisiible: false,
			visible: false,
			showContent: false,
		}
	},
	computed: {
		roundSizeRpx() {
			return uni.upx2px(+this.roundSize)
		},
	},
	methods: {
		show(cb = () => {}) {
			callback = cb
			this.visible = true
			this.overlayVisiible = true
			this.$nextTick(() => {
				this.showContent = true
			})
		},
		hide() {
			this.showContent = false
			this.overlayVisiible = false

			callback && callback()
		},
	},
}
</script>

<style lang="scss" scoped>
.v-popup {
	position: fixed;
	z-index: 999999;
	width: 0;
	height: 0;
	top: 0;
	left: 0;
	.popup-content {
		position: fixed;
		background: #fff;
		.close-icon {
			position: absolute;
			top: 20rpx;
			right: 20rpx;
			width: 40rpx;
			height: 40rpx;
			z-index: 99;
			cursor: pointer;
			&::before,
			&::after {
				content: "";
				position: absolute;
				top: 50%;
				left: 50%;
				width: 100%;
				height: 2rpx;
				background: #999;
				transform: translate(-50%, -50%) rotate(45deg);
			}
			&::after {
				transform: translate(-50%, -50%) rotate(-45deg);
			}
		}
		&.position-top {
			top: 0;
			left: 0;
			width: 100%;
			max-height: 90vh;
			overflow-y: auto;
			&.round {
				border-radius: 0 0 var(--round-size) var(--round-size);
			}
			&.safe-area-inset-top {
				top: constant(safe-area-inset-top);
				top: env(safe-area-inset-top);
			}
		}
		&.position-bottom {
			bottom: 0;
			left: 0;
			width: 100%;
			max-height: 90vh;
			overflow-y: auto;
			&.round {
				border-radius: var(--round-size) var(--round-size) 0 0;
			}
			&.safe-area-inset-bottom {
				bottom: constant(safe-area-inset-bottom);
				bottom: env(safe-area-inset-bottom);
			}
		}
		&.position-left {
			top: 0;
			left: 0;
			height: 100%;
			max-width: 70vw;
			overflow-x: auto;
			&.round {
				border-radius: 0 var(--round-size) var(--round-size) 0;
			}
			&.safe-area-inset-top {
				top: constant(safe-area-inset-top);
				top: env(safe-area-inset-top);
			}
			&.safe-area-inset-bottom {
				bottom: constant(safe-area-inset-bottom);
				bottom: env(safe-area-inset-bottom);
			}
		}
		&.position-right {
			top: 0;
			right: 0;
			height: 100%;
			max-width: 70vw;
			overflow-x: auto;
			&.round {
				border-radius: var(--round-size) 0 0 var(--round-size);
			}
			&.safe-area-inset-top {
				top: constant(safe-area-inset-top);
				top: env(safe-area-inset-top);
			}
			&.safe-area-inset-bottom {
				bottom: constant(safe-area-inset-bottom);
				bottom: env(safe-area-inset-bottom);
			}
		}

		&.slide-top-enter-active,
		&.slide-top-leave-active {
			transition: all var(--duration);
		}
		&.slide-top-enter,
		&.slide-top-leave-to {
			opacity: 0.7;
			transform: translateY(-100%);
		}

		&.slide-bottom-enter-active,
		&.slide-bottom-leave-active {
			transition: all var(--duration);
		}
		&.slide-bottom-enter,
		&.slide-bottom-leave-to {
			opacity: 0.7;
			transform: translateY(100%);
		}

		&.slide-left-enter-active,
		&.slide-left-leave-active {
			transition: all var(--duration);
		}
		&.slide-left-enter,
		&.slide-left-leave-to {
			opacity: 0.7;
			transform: translateX(-100%);
		}

		&.slide-right-enter-active,
		&.slide-right-leave-active {
			transition: all var(--duration);
		}
		&.slide-right-enter,
		&.slide-right-leave-to {
			opacity: 0.7;
			transform: translateX(100%);
		}
	}
}
</style>
